#include "udpServer.hpp"
#include "onlineUser.hpp"
#include <memory>
#include <fstream>
#include <unordered_map>
#include <signal.h>
#include <stdio.h>

using namespace std;
using namespace Server;

// const std::string dicttxt = "./dict.txt";

static void Usage(string proc)
{
    cout << "Usage:\n\t" << proc << " local_port\n\n";
}

// unordered_map<string,string> dict;

// static bool curstring(const string&target,string* s1,string*s2,const string &sep)
// {
//     auto pos = target.find(sep);
//     if(pos == string::npos)
//     {
//         return false;
//     }
//     *s1 = target.substr(0 , pos);
//     *s2 = target.substr(pos + sep.size());
//     return true;
// }

// static void initDict()
// {
//     ifstream in(dicttxt,std::ios::binary);
//     if(!in.is_open())
//     {
//         std::cerr << "open file "<<dicttxt<<" error"<<std::endl;
//         exit(OPEN_ERR);
//     }

//     string line;
//     std::string key,value;

//     while(getline(in,line))
//     {
//         //cout<<line<<endl;
//         if(curstring(line,&key,&value,":"))
//         {
//             dict.insert(make_pair(key,value));
//         }
//     }

//     in.close();

//     cout<<"load dict success"<<endl;
// }

// void reload(int signo)
// {
//     (void)signo;
//     initDict();
// }

// static void debugprint()
// {
//     for(auto& dt :dict)
//     {
//         cout<<dt.first<<" # "<<dt.second<<endl;
//     }
// }

// //demo1
// void handerMessage(int sockfd,string clientip,uint16_t clientport,string message)
// {
//     //就可以对messages进行特殊的业务处理，不用关心怎么来的
//     //server通信和业务逻辑解耦

//     string response_message;

//     auto iter = dict.find(message);
//     if(iter == dict.end())
//     {
//         response_message = "unknow";
//     }
//     else
//     {
//         response_message = iter->second;
//     }

//     //开始返回
//     struct sockaddr_in client;
//     bzero(&client,sizeof(client));//初始化为全0
//     client.sin_family = AF_INET;
//     client.sin_port = htons(clientport);
//     client.sin_addr.s_addr = inet_addr(clientip.c_str());

//     //sleep(10);

//     sendto(sockfd, response_message.c_str(), response_message.size(), 0, (struct sockaddr *)&client, sizeof(client));
// }

// //demo2
// void execCommand(int sockfd,string clientip,uint16_t clientport,string cmd)
// {
//     FILE *fp = popen(cmd.c_str(),"r");

//     string response;

//     if(fp == nullptr)
//     {
//         response = "error";
//     }

//     char line[1024];

//     while(fgets(line,sizeof(line),fp))
//     {
//         response += line;
//     }

//         //开始返回
//     struct sockaddr_in client;
//     bzero(&client,sizeof(client));//初始化为全0
//     client.sin_family = AF_INET;
//     client.sin_port = htons(clientport);
//     client.sin_addr.s_addr = inet_addr(clientip.c_str());

//     //sleep(10);

//     sendto(sockfd, response.c_str(), response.size(), 0, (struct sockaddr *)&client, sizeof(client));

//     pclose(fp);
// }

OnlineUser onlineuser;

// demo3
void routeMessage(int sockfd, string clientip, uint16_t clientport, string message)
{
    if (message == "online")
    {
        onlineuser.addUser(clientip, clientport);
    }

    if (message == "offline")
    {
        onlineuser.delUser(clientip, clientport);
    }

    if (onlineuser.isOnline(clientip, clientport))
    {
        onlineuser.broadcastMessage(sockfd,clientip, clientport,message);
    }
    else
    {
        // 开始返回
        struct sockaddr_in client;
        bzero(&client, sizeof(client)); // 初始化为全0
        client.sin_family = AF_INET;
        client.sin_port = htons(clientport);
        client.sin_addr.s_addr = inet_addr(clientip.c_str());

        string response = "please enter online";

        sendto(sockfd, response.c_str(), response.size(), 0, (struct sockaddr *)&client, sizeof(client));
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }

    uint16_t port = atoi(argv[1]);

    // signal(2,reload);
    // initDict();
    // debugprint();

    // std::unique_ptr<udpServer> usvr(new udpServer(handerMessage,port));
    // std::unique_ptr<udpServer> usvr(new udpServer(execCommand,port));

    std::unique_ptr<udpServer> usvr(new udpServer(routeMessage, port));

    usvr->initServer();
    usvr->start();

    return 0;
}
